package com.lwc.controller;


import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphO;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.lwc.service.impl.StockImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.alibaba.csp.sentinel.slots.block.RuleConstant.FLOW_GRADE_QPS;

@RestController
public class OrderController {
    @Autowired
    StockImpl stock;
    /**
     * fallback 异常
     * @return
     * blockHandler = "handlerBlockException",
     */
    @GetMapping("/order")
    @SentinelResource(value = "查询订单",blockHandler = "handlerBlockException",fallback = "fallback")
    public   Map get(){
        return getOrder3();
    }

@PostMapping("/getnum")
    public  Map save(){
Map map=new HashMap<>();
map.put("stock",stock.queryStock());
return map;
    }

@PostConstruct
    void  addRlowRules(){
        System.out.println("------addRlowRules----------");
        //定义一组流控规则
        List<FlowRule> list=new ArrayList<>();
        //定义规则
        FlowRule flowRule=new FlowRule("查询订单");
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);//限定qps  \
        flowRule.setCount(2);//阈值
        flowRule.setLimitApp("default"); //限制请求的来源 限制从哪些服务发来的请求
        list.add(flowRule);
        FlowRuleManager.loadRules(list);
    }

    /**
     * 访问目标资源出现异常是执行
     */

     public   Map fallback(Throwable e){
Map map=new HashMap<>();
map.put("code",21);
map.put("msg",e.toString());
return  map;
    }


    /**
     * 直接写类名 blockHandlerClass = {BlockException.class}   处理异常处理的方法所在的类，
     * 如果目标资源与处理异常的方法在同一个类中 这个参数可以忽少
     * blockHandler="handlerBlockException"  指定处理 Block异常的方法名称
     * @return
     */

    public  static  Map  getOrder3(){
        Map map=new HashMap();
        map.put("age",1451);
        map.put("name","dsa");

        return  map;

    }

    /**
     * 降级处理
     * @return
     */

     public   Map handlerBlockException(BlockException  e){
        Map map=new HashMap();
        map.put("code",100);
        map.put("msg","请求失败");
        return  map;
      }



    /**
     * 使用SphO定义资源
     * @return
     */
 public  static    Map getOrder2(){
Map map=new HashMap();
        if (SphO.entry("getOrder2")){   //定义临界资源没有到达限流  返回 true  返回的flase
            map.put("orderNum", "dd20240001");
            map.put("money", 3666);
            SphO.exit();   //关闭资源
        }else {
            map.put("code", 0);
            map.put("msg", "您请求的服务开小差了..");
        }
return  map;
    }


    /**
     * 使用sphU定义资源    使用 try catch  定义资源
     * @return
     */
    public static  Map getOrder() {
        Entry entry = null;
        Map map = new HashMap();
        try {
            entry = SphU.entry("getOrder"); //定义资源
            //资源的核心逻辑
            map.put("orderNum", "dd20240001");
            map.put("money", 3666);
        } catch (BlockException e) {
            //  throw new RuntimeException(e);
            //服务降级处理
            map.put("code", 0);
            map.put("msg", "您请求的服务开小差了..");
        } finally {
            if (null != entry)
                entry.exit();
        }

        return map;
    }



}
